package com.uchengwang.functions.http.core;

import android.os.Environment;
import android.support.annotation.NonNull;

import com.uchengwang.functions.http.config.BaseConfig;
import com.uchengwang.functions.http.listener.IBaseRequest;
import com.uchengwang.functions.http.listener.OnFileDownloadListener;
import com.uchengwang.functions.http.listener.OnFileUploadListener;
import com.uchengwang.ui.UChengApplication;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;
import java.util.Map;

import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.MediaType;
import okhttp3.MultipartBody;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;

/**
 * 处理文件上传或者下载的封装类
 * Created by U城网 on 2017/3/4.
 */

public class HttpFile {
    private static HttpFile httpFile;
    private static OkHttpClient okHttpClient;

    enum UploadType{
        IMAGE,//图片
        VEDIO,//视频
        AUDIO//音频

    }

    /**
     * 参数类型
     * "text", 文本
     * "image", 图片
     * "audio",音频
     * "video"，视频
     * "object",其他
     */
    private static final MediaType MEDIA_TYPE_TEXT = MediaType.parse("text/x-markdown; charset=utf-8");
    private static final MediaType MEDIA_TYPE_JPG = MediaType.parse("image/png");
    private static final MediaType MEDIA_TYPE_AUDIO = MediaType.parse("audio/mp3");
    private static final MediaType MEDIA_TYPE_VIDEO = MediaType.parse("video/mp4");
    private static final MediaType MEDIA_TYPE_OBJECT = MediaType.parse("application/octet-stream");
    private static final MediaType MEDIA_TYPE_JSON = MediaType.parse("application/json; charset=utf-8");

    private HttpFile(){}

    public static HttpFile getHttpFile() {
        if (httpFile == null){
            httpFile = new HttpFile();
            okHttpClient = UChengApplication.getHttpClient();
        }
        return httpFile;
    }

    /**
     * 文件下载
     * @param url 文件请求地址
     * @param localString 文件下载地址
     * @param listener 回调
     * */
    public void download(final String url, final String localString, final OnFileDownloadListener listener){
        Request request = new Request.Builder().url(url).build();
        okHttpClient.newCall(request).enqueue(new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {
                listener.onFailure(e);
            }

            @Override
            public void onResponse(Call call, Response response) throws IOException {
                InputStream is = null;
                byte[] buf = new byte[2048];
                int len = 0;
                FileOutputStream fos = null;
                // 储存下载文件的目录
                String savePath = isExistDir(localString);
                try {
                    is = response.body().byteStream();
                    long total = response.body().contentLength();
                    File file = new File(savePath, getNameFromUrl(url));
                    fos = new FileOutputStream(file);
                    long sum = 0;
                    while ((len = is.read(buf)) != -1) {
                        fos.write(buf, 0, len);
                        sum += len;
                        int progress = (int) (sum * 1.0f / total * 100);
                        // 下载中
                        listener.onLoading(total,progress);
                    }
                    fos.flush();
                    // 下载完成
                    listener.onSuccess(localString);
                } catch (Exception e) {
                    listener.onFailure(e);
                } finally {
                    try {
                        if (is != null)
                            is.close();
                    } catch (IOException e) {
                    }
                    try {
                        if (fos != null)
                            fos.close();
                    } catch (IOException e) {
                    }
                }

            }
        });

    }

    /**
     * 文件上传
     * @param fileType
     * @param url
     * @param params
     * @param files
     * @param listener
     *
     * */

    public void uoload(UploadType fileType, String url, IBaseRequest params, List<File> files, final OnFileUploadListener listener){
        MultipartBody.Builder multipartBodyBuilder = new MultipartBody.Builder();
        multipartBodyBuilder.setType(MultipartBody.FORM);
        //遍历map中所有参数到builder
        if (params != null){
            Map<String, Object> map = params.getData();
            for (String key : map.keySet()) {
                multipartBodyBuilder.addFormDataPart(key, (String) map.get(key));
            }
        }
        //遍历paths中所有图片绝对路径到builder，并约定key如“upload”作为后台接受多张图片的key
        //里面的参数名可修改 和后台一致
        if (files != null){
            for (File file : files) {
                switch (fileType){
                    case AUDIO:
                        multipartBodyBuilder.addFormDataPart("audio", file.getName(), RequestBody.create(MEDIA_TYPE_AUDIO, file));
                        break;
                    case IMAGE:
                        multipartBodyBuilder.addFormDataPart("image", file.getName(), RequestBody.create(MEDIA_TYPE_JPG, file));
                        break;
                    case VEDIO:
                        multipartBodyBuilder.addFormDataPart("vedio", file.getName(), RequestBody.create(MEDIA_TYPE_VIDEO, file));
                        break;


                }

            }
        }
        //构建请求体
        RequestBody requestBody = multipartBodyBuilder.build();
        //补全请求地址
        String requestUrl = String.format("%s/%s", BaseConfig.BaseURL, url);

        Request.Builder RequestBuilder = new Request.Builder();
        RequestBuilder.url(requestUrl);// 添加URL地址

        RequestBuilder.post(requestBody);
        Request request = RequestBuilder.build();
        okHttpClient.newCall(request).enqueue(new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {
                listener.onFailure(e);
                call.cancel();
            }

            @Override
            public void onResponse(Call call, Response response) throws IOException {
                String str = response.body().string();
                //到时候根据后台返回参数封装bean
//                listener.onSuccess(null);
                call.cancel();
            }
        });


    }



    /**
     * @param saveDir
     * @return
     * @throws IOException
     * 判断下载目录是否存在
     */
    private String isExistDir(String saveDir) throws IOException {
        // 下载位置
        File downloadFile = new File(Environment.getExternalStorageDirectory(), saveDir);
        if (!downloadFile.mkdirs()) {
            downloadFile.createNewFile();
        }
        String savePath = downloadFile.getAbsolutePath();
        return savePath;
    }

    /**
     * @param url
     * @return
     * 从下载连接中解析出文件名
     */
    @NonNull
    private String getNameFromUrl(String url) {
        return url.substring(url.lastIndexOf("/") + 1);
    }


}
